from datetime import datetime

from coin.support.accounting.logic.db_connector import InfluxdbConnector
from coin.support.accounting.logic.db_importer import AccountInfoImporter
from xunkemgmt.support.accounting.logic.query_request import *


class InfluxdbAccountInfoImporter(AccountInfoImporter):
  def __init__(self, db_config):
    self._connector = InfluxdbConnector(db_config)

  def insert_account_balance_history(self, request_list, response_list):
    assert len(request_list) == len(response_list)

    now = datetime.utcnow().isoformat() + "Z"
    results = []
    for request, response in zip(request_list, response_list):
      try:
        balance_total = response["balance"]
        # necessary to avoid empty fields
        balance_total["__dummy__"] = 0
        d = {
            "measurement": "balance_detail",
            "time": now,
            "tags": request._asdict(),
            "fields": balance_total,
        }
        results.append(d)
      except KeyError:
        continue
      except Exception as e:
        print('Fail to insert balance history to influxdb', request, type(e), e)
        continue
    self._connector.write_points(results)

  def insert_account_position_history(self, request_list, response_list):
    assert len(request_list) == len(response_list)

    now = datetime.utcnow().isoformat() + "Z"
    results = []
    for request, response in zip(request_list, response_list):
      try:
        position_total = response["position"]
        # necessary to avoid empty fields
        position_total["__dummy__"] = 0
        d = {
            "measurement": "position_detail",
            "time": now,
            "tags": request._asdict(),
            "fields": position_total,
        }
        results.append(d)
      except KeyError:
        continue
      except Exception as e:
        print('Fail to insert position history to influxdb', request, type(e), e)
        continue
    self._connector.write_points(results)

  def insert_balance_estimate_history(self, request_list, response_list):
    self._insert_estimate_history_impl(request_list, response_list, 'balance')

  def insert_position_estimate_history(self, request_list, response_list):
    self._insert_estimate_history_impl(request_list, response_list, 'position')

  def _insert_estimate_history_impl(self, request_list, response_list, estimate_type):
    if estimate_type == 'balance':
      measurement = 'balance_estimate_detail'
    elif estimate_type == 'position':
      measurement = 'position_estimate_detail'
    else:
      raise ValueError('Unknown estimate_type: %s' % estimate_type)

    assert len(request_list) == len(response_list)
    now = datetime.utcnow().isoformat() + "Z"
    results = []
    for request, response in zip(request_list, response_list):
      try:
        if not response:  # Fail to position estimate
          continue
        fields = {
            'coin_value': response.estimate.coin_value,
            'quote_value': response.estimate.quote_value,
            'total_value': response.estimate.total_value
        }
        d = {
            "measurement": measurement,
            "time": now,
            "tags": request._asdict(),
            "fields": fields,
        }
        results.append(d)
      except Exception as e:
        print('Fail to insert %s estimate to influxdb' % estimate_type, request, type(e), e)
        continue
    self._connector.write_points(results)
